/*
 * @Author: master
 * @Date: 2022-03-28 16:40:46
 * @LastEditTime: 2022-04-15 20:56:34
 * @Description: 启动服务
 */
const path = require('path');
const request = require('request');
const { getAllProPath, getParseUrl, isFile, isIndexHtmlJs, colors, copySrcDirToTarDir } = require('./util.js'); // node服务工具
const inquirer = require('inquirer'); // 面板选择
// 默认配置
const defaultConfig = {
  base: '/', // 开发或生产环境服务的公共基础路径
  nodeEnv: process.env.NODE_ENV,
};
const runInit = callBack => {
  // 所有项目列表、获取所有项目地址
  const proList = getAllProPath(path.join(__dirname, '../..', 'main/project'));
  /**
   * 执行启动
   */
  const implement = async answer => {
    // 获取选中的项目
    const project = proList.filter(folder => folder.name === answer.name)[0];
    // 判断每个项目是否包含必须的index.html和index.js
    const state = isIndexHtmlJs(project.path);
    // 判断状态
    if (state) {
      // 定义vite的打包入口
      // vite的配置
      const viteConfig = {
        // 项目名称
        name: `${project.name}`,
        // 入口
        root: `${project.path}`,
        // vite的默认配置
        ...defaultConfig,
      };
      // 判断自定义文件是否存在
      const state = await isFile(`${project.path}/vite.config.js`);
      // 配置项
      let config = {};
      // 判断自定义文件是否存在
      if (state) {
        try {
          // 每个项目的vite的配置;
          config = require(`${project.path}/vite.config.js`);
        } catch (e) {
          console.log(colors('red'), e);
          config = {};
        }
        /**
         * 如果存在模拟登录
         * 模拟用户信息（项目下vite.config.js文件必须存在simulation对象）
         */
        if (config && config.simulation && (process.env.NODE_ENV === 'dev' || config.nodeEnv === 'dev')) {
          await simulationUserInfo(config.simulation);
        }
      }
      // 往node的process进行全局变量添加配置属性
      process.env.viteConfig = JSON.stringify({
        ...viteConfig,
        ...config,
      });
      callBack();
    } else {
      console.log(colors('red'), '错误：项目内没有包含必要文件!!---（index.html 和 index.js）');
      executeTemPro(project);
    }
  };
  /**
   * 当前执行操作是在具体业务项目工程中，则直接启动
   */
  const parseUrl = getParseUrl(process.env.INIT_CWD);
  if (parseUrl && parseUrl.base) {
    const answer = proList.filter(pro => pro.name === parseUrl.base)[0];
    if (answer) {
      // 执行启动
      return implement(answer);
    }
  }
  /**
   * 项目目录处理
   */
  if (!proList || proList.length === 0) {
    return console.log(colors('red'), '错误：请创建项目!!');
  } else if (proList && proList.length === 1) {
    const answer = proList[0];
    if (answer && answer.name.includes('_back') === false) {
      // 执行启动
      return implement(answer);
    }
  }
  // 执行命令行命令
  inquirer
    .prompt([
      {
        type: 'list',
        message: '请选择一个项目：',
        name: 'name',
        choices: proList.map(folder => folder.name).filter(folderName => folderName.includes('_back') === false),
      },
    ])
    .then(async answer => {
      // 执行启动
      implement(answer);
    })
    .catch(e => {
      console.log(colors('yellow'), '警告：出现异常，程序终止运行！');
    });
};
/**
 * 执行模板程序，目的是快速拷贝已有模板程序到指定项目中
 * @param {*} project 要执行的项目信息
 */
const executeTemPro = project => {
  inquirer
    .prompt([
      {
        type: 'list',
        message: '是否导入模板：',
        name: 'name',
        choices: [{ name: '是' }, { name: '否' }],
      },
    ])
    .then(answer => {
      if (answer && answer.name === '是') {
        // 获取模板列表
        const temList = getAllProPath(path.resolve(__dirname, '../template'));
        inquirer
          .prompt([
            {
              type: 'list',
              message: '导入模板：',
              name: 'name',
              choices: temList.map(folder => folder.name).concat({ name: '取消' }),
            },
          ])
          .then(async answer => {
            if (answer.name === '取消') {
              return console.log(colors('green'), '已取消!!');
            }
            // 获取选中的项目
            const tem = temList.filter(folder => folder.name === answer.name)[0];
            /**
             * 拷贝文件夹内容到另一个文件夹内
             */
            copySrcDirToTarDir(tem.path, project.path, () => {
              return console.log(colors('green'), '导入完成!!');
            });
          });
      }
    });
};
/**
 * 模拟用户信息（项目下vite.config.js文件必须存在simulation对象）
 * simulation: {
    // 服务地址，ip和端口
    http: 'https://192.168.240.78:26000',
    // 服务名称
    name: '/auth/login',
    body: {
      // 用户名
      userId: 'h210744344',
      // 密码
      password: 't5/oMgwUCmO/GeMHBAQ2Cg==',
      systemCode: 'SYS_CODE_SSO',
      loginType: 0,
      languageCode: 'zh-CN',
    },
    // 自定义token的key值
    customHeaderTokenKey: 'Authorization',
    // 自定义返回数据的JwtToken的key值
    customDataJwtToken: 'jwtToken',
  }
 * @returns 
 */
const simulationUserInfo = simulation => {
  process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
  // 请求地址
  const url = `${simulation.http}${simulation.name}`;
  // 请求参数
  let body = {
    checkType: 0,
    idcard: '',
    isPc: true,
    passWord: simulation.password,
    phone: '',
    userId: simulation.userId,
  };
  // 如果项目配置里面包含了请求体body，则采用配置文件里设置的body
  if (simulation.body) {
    body = simulation.body;
  }
  console.log(colors('bright'), `模拟请求地址：${url}`);
  console.log(colors('bright'), `请求的参数：${JSON.stringify(body)}`);
  const options = {
    method: 'post',
    url: url,
    timeout: 10000,
    body: body,
    json: true,
  };
  return new Promise(resolve => {
    try {
      request(options, (error, response, body) => {
        if (!error && response.statusCode === 200) {
          if (body.data) {
            // 返回的数据
            simulation.commandResult = body.data;
          } else {
            console.log(colors('red'), '错误：模拟登录请求错误');
          }
        } else if (error && error.code === 'ETIMEDOUT') {
          console.log(colors('red'), '错误：请求超时');
        } else {
          console.log(colors('red'), '错误：模拟登录请求错误');
        }
        resolve();
      });
    } catch (e) {
      console.log(colors('red'), e);
      console.log(colors('red'), '错误：模拟登录请求错误');
    }
  });
};
module.exports = runInit;
